package com.cskaoyan.javase.introduction;

/**
 * @description: 引入递归
 * @author: wuguidong@cskaoyan.onaliyun.com
 **/

/**
 * 回到Java当中，方法是可以调用方法的，特别的，一个方法当中再次调用这个方法，就像故事里提到同样的故事一样
 * 我们把方法在运行时调用自身的情况，称之为递归，又叫做递归调用
 *
 * 当你使用递归的时候注意事项：
 * 1，使用递归，一定要有出口，什么时候结束这个递归。称之为递归的出口
 * 数学家高斯的故事：1+...+100和
 * 2，如果这个方法递归有出口，那么就一定能保证不会栈溢出吗？
 * 如果递归的出口非常远，还没有让我走到出口，我已经饿死了
 * 这时候仍然会栈溢出
 * 所以即便是方法有递归出口，仍然要重点考虑递归的次数，这个次数不能太大，不能超过栈空间的大小
 *
 * StackOverflow.com 全球最大的程序员知识问答平台 相当于程序员的知乎 最大的同性交友平台 一问一答 就产生了感情
 * github 偏向于 项目
 *
 */
public class Demo {
    public static void main(String[] args) {
        System.out.println(sum(100000));
        //while (true){
        //    System.out.println("11111");
        //}
        /**
         * 这个调用有什么结果呢？
         * 分析：
         * sum(10) = 10 + sum(9)
         * sum(9) = 9 + sum(8)
         * sum(8) = 8 + sum(7)
         * sum(7) = 7 + sum(6)
         * ....
         * sum(1) = 1 + sum(0)
         * sum(0) = 0
         * 这个过程是停不下来的
         * 猜测一下 程序的结果：
         * 1，死循环
         * 2，程序崩溃了 报错
         * 3，电脑受不了了，自爆了，会议结束了
         *
         * 这里程序会崩溃，会报错
         * StackOverflowError：栈溢出错误
         * Method 'sum()' recurses infinitely, and can only end by throwing an exception
         * 这个方法无限递归，只能通过抛出异常的方式停止下来 StackOverflowError
         * Access can be private 访问权限可以用private修饰 代码安全考虑的提示
         *
         * StackOverflowError：栈溢出，什么栈？jvm栈还是本地方法栈
         * jvm栈溢出了
         *
         *
         */

    }

    //写一个简单的递归方法
    public static int sum(int a) {
        //写一个递归的出口
        if (a == 0) {
            //终止这个方法
            return 0;
        } else {
            return a + sum(a - 1);
        }
    }
}
